﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;

using Styx;
using Styx.Common;
using Styx.CommonBot;
using Styx.CommonBot.Profiles;
using Styx.Pathing;						
using Styx.WoWInternals;				
using Styx.WoWInternals.WoWObjects;		
using Styx.Plugins;						

namespace rndbuddy
{
    static class movement_watcher
    {
        public static double moved = 100;
        public static int ticked = 0;
        public static DateTime last_moved;
        public static bool tried_move_to_unstuck;

        public static string[] pos_old = new string[] { "1","1"};

        public static bool tried_bot_restart;

        public static void trk_move()
        {
            //don't track if not running or not ready
            if (!TreeRoot.IsRunning || !StyxWoW.IsInGame || !StyxWoW.IsInWorld)
                return;
			
			//don't track if in combat
			if (StyxWoW.Me.Combat)
                return;
			
            //dont track if not gather botbase
            if (!BotController.is_gather_botbase())
                return;

            //exception if we got rezz illness
            if (StyxWoW.Me.HasAura("Resurrection Sickness"))
            {
                rndbuddy.log("movement detection override due to resseruction sickness");
                ticked = 0;
                moved += 100;
                return;
            }

            //calc position form old to now
            double d = calc_dist(pos_old[0], pos_old[1], StyxWoW.Me.X.ToString(), StyxWoW.Me.Y.ToString());

            if (d > 0)
                movement_watcher.last_moved = System.DateTime.Now;
            check_idle_in_world();    
            
            //add this to moved sum
            moved += d;

            //update old position
            pos_old[0] = StyxWoW.Me.X.ToString();
            pos_old[1] = StyxWoW.Me.Y.ToString();

            //increase tick
            ++ticked;

            //check
            if (ticked > settings.movement_watcher_samples)
            {
                rndbuddy.log("running movement check");
                if (moved < settings.movement_watcher_min_distance)
                {
                    if (!tried_bot_restart)
                    {
                        //trying to restart bot before killing it
                        rndbuddy.logcrit("Trying to recover bot");
                        rndbuddy.log("Stopping TreeRoot");
                        TreeRoot.Stop();

                        rndbuddy.log("Collecting Garbage");
                        Tripper.Navigation.WowNavigator a = new Tripper.Navigation.WowNavigator();
                        a.GarbageCollectTiles(true);

                        rndbuddy.log("Forcing new Profile");
                        ProfileHandler.get_profile();

                        rndbuddy.log("Starting ThreadRoot");
                        TreeRoot.Start();

                        ticked = 0;
                        moved = 100;

                        tried_bot_restart = true;
                    }
                    else
                    {
                        rndbuddy.log("Killing Bot for not moving");
                        rndbuddy.forceQuit(false, "Bot is not moving");
                        return;
                    }
                }

                ticked = 0;
                moved = 0;
                return;
            }
        }

        public static void check_idle_in_world()
        {
            if (tried_move_to_unstuck)
            {
                rndbuddy.logcrit("Seems like the last unstuck attempt has failed. Killing Honorbuddy");
                PlayerSecurity.kill_hb("unable to recover from stuck");
                return;
            }

            double d = System.DateTime.Now.Subtract(last_moved).TotalSeconds;
            if (d > settings.max_idle_time)
            {
                rndbuddy.logcrit("seems like you're not moving, i'll give you a hand");
                tried_move_to_unstuck = true;
                movement_controller.unstuck_attempt();
                rndbuddy.log("downloading new profile");
                ProfileHandler.get_profile();
            }
        }

        public static double calc_dist(string old_x, string old_y, string new_x, string new_y)
        {
  			float x1f = float.Parse(old_x, System.Globalization.CultureInfo.InvariantCulture);
  			float x2f = float.Parse(new_x, System.Globalization.CultureInfo.InvariantCulture);
 			float y1f = float.Parse(old_y, System.Globalization.CultureInfo.InvariantCulture);
  			float y2f = float.Parse(new_y, System.Globalization.CultureInfo.InvariantCulture);

  			return Math.Sqrt(((x1f-x2f)*(x1f-x2f))+((y1f-y2f)*(y1f-y2f)));
        }
       
    }
}
